#include<iostream>
#include<cstddef>

struct Header
{
        alignas(64) char pad0;
        int s1;
        alignas(64) char pad1;
        int s2;
};

int main(void)
{
        std::cout<< "sizeof Header: " << sizeof(Header) << std::endl;
        std::cout<< "alignof Header: " << alignof(Header) << std::endl;
        std::cout<< "max align: " << alignof(std::max_align_t) << std::endl;
        std::cout<< "max size: " << sizeof(std::max_align_t) << std::endl;

        Header* p1 = new Header;
        std::cout<< (void*)&p1->pad0 << std::endl;

        char buf[10240];
        Header* p2 = new(&buf[1]) Header;
        std::cout<< (void*)&buf[1]<< " " << (void*)&p2->pad0 << std::endl;

        Header p3;
        std::cout<< (void*)&p3.pad0 << std::endl;

        delete p1;
}

/*********************************************
在g++5.4上编译，运行结果如下：
sizeof Header: 128
alignof Header: 64
max align: 16
max size: 32
0xedd030
0x7ffc103db6f1 0x7ffc103db6f1
0x7ffc103db640
可以看到：
1. alignas对栈中的变量有效，严格按照声明中的值对齐
2. alignas对堆中的变量无效，只按16byte对齐
3. alignas对placement new完全无效。placement buffer的值是多少，返回值就是多少，placement new不做任何align处理。

当alignas的值太大会如何？
把代码中的alignas(64)换成align(512)，在g++5.4上编译报警告如下：
g++ a.cc --std=c++11
a.cc:6:20: warning: requested alignment 512 is larger than 128 [-Wattributes]
  alignas(512) char pad0;
                    ^
a.cc:8:20: warning: requested alignment 512 is larger than 128 [-Wattributes]
  alignas(512) char pad1;
运行结果如下：
sizeof Header: 16
alignof Header: 4
max align: 16
max size: 32
0xd66030
0x7ffef9823641 0x7ffef9823641
0x7ffef9823630
可见当alignas的值过大时，g++5.4忽略了该属性，一切按没有指定alignas处理。

g++10.2/c++11:
[mdy@localhost ~]$ g++ a.cc --std=c++11
[mdy@localhost ~]$ ./a.out
sizeof Header: 1024
alignof Header: 512
max align: 16
max size: 32
0x10db2c0
0x7ffc406113f1
0x7ffc40610e00
可见支持按512byte对齐，但是对堆中的变量无效。

g++10.2/c++14:
[mdy@localhost ~]$ g++ a.cc --std=c++14
[mdy@localhost ~]$ ./a.out
sizeof Header: 1024
alignof Header: 512
max align: 16
max size: 32
0x5a82c0
0x7ffff95b1bf1
0x7ffef95b1600
结果同上，支持按512byte对齐，但是对堆中的变量无效。

g++10.2/c++17:
[mdy@localhost ~]$ g++ a.cc --std=c++17
[mdy@localhost ~]$ ./a.out
sizeof Header: 1024
alignof Header: 512
max align: 16
max size: 32
0xf40400
0x7ffe767573f1
0x7ffe76756e00
此时，alignas(512)对堆中的变量也生效了。

实际上，用c++11/c++14标准编译时，是有警告的。用-Wall选项编译，如下所示：
g++ a.cc --std=c++11 -Wall
a.cc: 在函数‘int main()’中:
a.cc:19:26: 警告：‘new’ of type ‘Header’ with extended alignment 512 [-Waligned-new=]
   19 |         Header* p1 = new Header;
      |                          ^~~~~~
a.cc:19:26: 附注：uses ‘void* operator new(std::size_t)’, which does not have an alignment parameter
a.cc:19:26: 附注：use ‘-faligned-new’ to enable C++17 over-aligned new support

而用c++17标准编译时，不会有警告信息。

结论：
1. alignas对placement new完全无效
2. 当alignas的值不超过编译器的限制时，对栈中的变量总是有效。目前看g++5.4中的限制是128byte，g++7.5及以上的版本没有限制。
3. 当alignas的值超过alignof(std::max_align_t)时，仅在c++17及以上标准中对堆中的变量才有效。
************************************************/
